﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.UI;
using System.Web.Handlers;
using System.Reflection;
using System.Web.Configuration;

namespace Cwing.UI.Mvc
{
    public class ValidationHelper
    {
        private static ValidationHelper helper;

        static ValidationHelper()
        {
            helper = new ValidationHelper();
        }

        private ValidationHelper()
        {
        }

        public HtmlHelper Html { get; set; }

        public static ValidationHelper Helper
        {
            get
            {
                if (helper == null)
                {
                    helper = new ValidationHelper();
                }

                return helper;
            }
        }

        //for TextBox
        public String TextBox(String name, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextBox(name);
        }

        public string TextBox(string name, object value, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextBox(name, value, null);
        }

        public string TextBox(string name, object value, IDictionary<string, object> htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextBox(name, value, htmlAttributes);
        }

        public string TextBox(string name, object value, object htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextBox(name, value, htmlAttributes);
        }

        //for password
        public string Password(string name, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.Password(name);
        }

        public string Password(string name, object value, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.Password(name, value);
        }

        public string Password(string name, object value, IDictionary<string, object> htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.Password(name, value, htmlAttributes);
        }

        public string Password(string name, object value, object htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.Password(name, value, htmlAttributes);
        }

        //for texteara
        public string TextArea(string name, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name);
        }

        public string TextArea(string name, IDictionary<string, object> htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, htmlAttributes);
        }

        public string TextArea(string name, object htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, htmlAttributes);
        }

        public string TextArea(string name, string value, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, value, null);
        }

        public string TextArea(string name, string value, IDictionary<string, object> htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, value, htmlAttributes);
        }

        public string TextArea(string name, string value, object htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, value, htmlAttributes);
        }

        public string TextArea(string name, string value, int rows, int columns, IDictionary<string, object> htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, value, rows, columns, htmlAttributes);
        }

        public string TextArea(string name, string value, int rows, int columns, object htmlAttributes, ValidationViewPage page, Configure config)
        {
            config.Name = name;
            page.Configures.Add(config);
            return Html.TextArea(name, value, rows, columns, htmlAttributes);
        }

        public String ValidationSummary(string name, ValidationViewPage page, Boolean useForMandatory)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new NullReferenceException("name for error contain can't be empty.");
            }

            page.ValidationSummaries.Add(new ValidationSummary() { Name = name, UseForMandatory = useForMandatory });

            return String.Format("<ul id=\"{0}\" ></ul>", name);
        }

        //Output Script Reference
        public String ScriptReference(ValidationViewPage page, Boolean includeTag)
        {
            if (page.RendScriptReference == false)
            {
                ValidationViewMasterPage master = page.Master as ValidationViewMasterPage;
                if (master != null && master.RendScriptReference == true)
                {
                    page.RendScriptReference = true;

                    return String.Empty;
                }
                else
                {
                    master.RendScriptReference = true;

                    page.RendScriptReference = true;
                }
                String str = page.ClientScript.GetWebResourceUrl(typeof(Cwing.UI.Controls.ValidationPage), "Cwing.UI.Validation.js");
                if (includeTag == true)
                {
                    return String.Format("<script type=\"text/javascript\" src=\"{0}\"></script>\r\n", str);
                }
                else
                {
                    return str;
                }
            }
            else
            {
                return String.Empty;
            }
        }

        public String ScriptReference(ValidationViewMasterPage master, Boolean includeTag)
        {
            if (master.RendScriptReference == false)
            {
                master.RendScriptReference = true;

                if (master.Page is ValidationViewPage)
                    ((ValidationViewPage)master.Page).RendScriptReference = true;

                String str = master.Page.ClientScript.GetWebResourceUrl(typeof(Cwing.UI.Controls.ValidationPage), "Cwing.UI.Validation.js");
                if (includeTag == true)
                {
                    return String.Format("<script type=\"text/javascript\" src=\"{0}\"></script>\r\n", str);
                }
                else
                {
                    return str;
                }
            }
            else
            {
                return String.Empty;
            }
        }

        public String ScriptData(ValidationViewPage page, Boolean includeTag)
        {
            if (page.RendScriptReference == false)
            {
                throw new ValidationScriptExecption("Please initial validation object first.");
            }

            if (page.RendScript == false)
            {
                page.RendScript = true;

                StringBuilder builder = new StringBuilder(1024);

                //validate configuration
                for (int i = 0; i < page.Configures.Count; i++)
                {
                    String script = page.Configures[i].ToScript();
                    if (!String.IsNullOrEmpty(script))
                    {
                        builder.AppendFormat("CW.Add({0});\r\n", script);
                    }
                }

                //validation summary
                for (int i = 0; i < page.ValidationSummaries.Count; i++)
                {
                    builder.AppendFormat("CW.AddErrorList({0}ID:\"{1}\",Title:\"{2}\",TC:\"{3}\",MC:\"{4}\",M:{5}{6});\r\n", "{", page.ValidationSummaries[i].Name, page.ValidationSummaries[i].Title, page.ValidationSummaries[i].TitleCssClass, page.ValidationSummaries[i].MessageCssClass, page.ValidationSummaries[i].UseForMandatory.ToString().ToLower(), "}");
                }

                //config
                builder.AppendFormat("CW.MandatoryMessage=\"{0}\";\r\n", ValidationConfigHelper.MandatoryMessage());
                builder.AppendFormat("CW.MandatoryColor=\"{0}\";\r\n", ValidationConfigHelper.section == null ? "#FFC030" : ValidationConfigHelper.section.MandatoryColor);
                builder.AppendFormat("CW.FailureColor=\"{0}\";\r\n", ValidationConfigHelper.section == null ? "#C03000" : ValidationConfigHelper.section.FailureColor);
                builder.Append("CW.Validation.Initial();\r\n");

                if (includeTag)
                {
                    return String.Format("\r\n<script type=\"text/javascript\">\r\n//<![CDATA[\r\n{0}//]]>\r\n</script>\r\n", builder.ToString());
                }
                else
                {
                    return builder.ToString();
                }
            }
            else
            {
                return String.Empty;
            }
        }

    }
}
